package pikes.samples.countries.ui.peak;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.springframework.web.servlet.support.RequestContext;

import pikes.ecma.ExpressionStatement;
import pikes.ecma.FunctionDeclaration;
import pikes.ecma.IExpression;
import pikes.ecma.SourceElement;
import pikes.peak.RequestIndependentProperty;
import pikes.peak.RequestProperty;

public class DynamicFunctionDeclaration implements RequestProperty<SourceElement> {

	private CharSequence functionName = null;

	private List<RequestProperty<CharSequence>> formalParameters = new LinkedList<RequestProperty<CharSequence>>();

	private List<RequestProperty<? extends SourceElement>> body = new LinkedList<RequestProperty<? extends SourceElement>>();

	public DynamicFunctionDeclaration(final CharSequence functionName) {
		this.functionName = functionName;
	}

	public SourceElement getValue(Map model, RequestContext requestContext) throws Exception {
		FunctionDeclaration functionDeclaration = new FunctionDeclaration(functionName);

		for (RequestProperty<CharSequence> formalParameter : formalParameters) {
			functionDeclaration.add(formalParameter.getValue(model, requestContext));
		}
		for (RequestProperty<? extends SourceElement> sourceElement : body) {
			functionDeclaration.add(sourceElement.getValue(model, requestContext));
		}
		return functionDeclaration;
	}

	public void addCode(IExpression expression) {
		this.addCode(new ExpressionStatement(expression));
	}

	public void addCode(SourceElement sourceElement) {
		this.addCode(new RequestIndependentProperty<SourceElement>(sourceElement));
	}

	public void addCode(RequestProperty<? extends SourceElement> sourceElement) {
		body.add(sourceElement);
	}

	public void addFormalParameter(CharSequence formalParameter) {
		this.addFormalParameter(new RequestIndependentProperty<CharSequence>(formalParameter));
	}

	public void addFormalParameter(RequestProperty<CharSequence> formalParameter) {
		formalParameters.add(formalParameter);
	}
}